package com.zmj.dubboannotation.consumermobile.handle;

import com.zmj.dubboannotation.serviceapi.api.BaseException;
import com.zmj.dubboannotation.serviceapi.enums.ResultEnum;
import com.zmj.dubboannotation.serviceapi.exception.MallAuthorException;
import com.zmj.dubboannotation.serviceapi.exception.OrderException;
import com.zmj.dubboannotation.serviceapi.exception.ProductException;
import com.zmj.dubboannotation.serviceapi.exception.ResponseBankException;
import com.zmj.dubboannotation.serviceapi.utils.ResultVOUtil;
import com.zmj.dubboannotation.serviceapi.vo.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.crossstore.ChangeSetPersister;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.lang.reflect.InvocationTargetException;
import java.util.List;


/**
 * 统一异常拦截器
 * Created by: meijun
 * Date: 2018/09/15 18:59
 */
@RestControllerAdvice
@Slf4j
public class ExceptionHandle {

    /**
     *  校验错误拦截处理
     *
     * @param exception 错误信息集合
     * @return 错误信息
     */
    @ExceptionHandler(BindException.class)
    public ResultVO validationBodyException(BindException  exception){

        BindingResult result = exception.getBindingResult();
        if (result.hasErrors()) {

            List<ObjectError> errors = result.getAllErrors();

            errors.forEach(p ->{

                FieldError fieldError = (FieldError) p;
                log.error("Data check failure : object{"+fieldError.getObjectName()+"},field{"+fieldError.getField()+
                        "},errorMessage{"+fieldError.getDefaultMessage()+"}");

            });

        }
        return ResultVOUtil.error("请填写正确信息");
    }

    /**
     * 参数类型转换错误
     *
     * @param exception 错误
     * @return 错误信息
     */
    @ExceptionHandler(HttpMessageConversionException.class)
    public ResultVO parameterTypeException(HttpMessageConversionException exception){

        log.error(exception.getCause().getLocalizedMessage());
        return ResultVOUtil.error("类型转换错误");

    }

    /**
     * 商城统一拦截
     * @param e
     * @return
     */
    @ExceptionHandler(MallAuthorException.class)
    @ResponseBody
    public ResultVO handlerMallAuthorizeException(MallAuthorException e) {
        log.error("[MallAuthorException] error日志: {}" , e.getStackTrace());
        return ResultVOUtil.error(e.getMessage());
    }

    /**
     * 订单异常拦截
     * @param e
     * @return
     */
    @ExceptionHandler(value = OrderException.class)
    @ResponseBody
    public ResultVO handlerOrderException(OrderException e) {
        log.error("[handlerOrderException] error日志: {}" , e.getStackTrace());
        return ResultVOUtil.error(e.getMessage());
    }

    /**
     * 商品异常拦截
     * @param e
     * @return
     */
    @ExceptionHandler(value = ProductException.class)
    @ResponseBody
    public ResultVO handlerProductException(ProductException e) {
        return ResultVOUtil.error(e.getMessage());
    }

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResultVO handlerMallAuthorizeExceptionServerError(Exception e) {
        log.error("[handlerMallAuthorizeExceptionServerError] error日志: {}" , e.getStackTrace());
        if (e instanceof org.springframework.web.servlet.NoHandlerFoundException) {
            return ResultVOUtil.error(ResultEnum.RESTFUL_API_NOTFOUND);
        }
        if (e instanceof ChangeSetPersister.NotFoundException) {
            return ResultVOUtil.error(ResultEnum.RESTFUL_API_NOTFOUND);
        }
        //反射异常
        if (e instanceof InvocationTargetException) {
            return ResultVOUtil.error(ResultEnum.NOT_TOKEN);
        }
        //格式转换异常
        if (e instanceof NumberFormatException) {
            return ResultVOUtil.error(ResultEnum.NOT_TOKEN);
        }
        if (e instanceof MallAuthorException) {
            return this.handlerMallAuthorizeException( (MallAuthorException)e);
        }
        if (e instanceof OrderException) {
            return this.handlerOrderException( (OrderException)e);
        }
        if (e instanceof ProductException) {
            return this.handlerProductException( (ProductException)e);
        }
        if (e instanceof ResponseBankException) {
            this.handlerResponseBankException( (ResponseBankException)e);
        }
        if (e instanceof BaseException) {
            return ResultVOUtil.error(ResultEnum.COLLECTION_MSG);
        }
        return ResultVOUtil.error(ResultEnum.RESTFUL_API_ERROR);

    }

    @ExceptionHandler(value = ResponseBankException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public void handlerResponseBankException(ResponseBankException e) {
        log.error("[ResponseBankException] error日志: {}" , e.getStackTrace());

    }
}
